package com.boruan.shengtangfeng.core.service.impl;

import com.boruan.shengtangfeng.core.dao.*;
import com.boruan.shengtangfeng.core.dto.*;
import com.boruan.shengtangfeng.core.entity.*;
import com.boruan.shengtangfeng.core.service.IClassAndService;
import com.boruan.shengtangfeng.core.service.IClassManagementService;
import com.boruan.shengtangfeng.core.utils.Consts;
import com.boruan.shengtangfeng.core.utils.GlobalReponse;
import com.boruan.shengtangfeng.core.utils.TencentUtil;
import com.boruan.shengtangfeng.core.vo.ClassAndVo;
import org.beetl.sql.core.engine.PageQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 @author: guojiang
 @Description:班级管理
 @date:2021/4/28
 */
@Service
@Transactional(readOnly = false)
public class ClassManagementServiceImpl implements IClassManagementService {

    @Autowired
    private ISchoolDao schoolDao;
    @Autowired
    private IUserDao userDao;
    @Autowired
    private IClassAndDao classAndDao;
    @Autowired
    private IClassAndService classAndService;
    @Autowired
    private IClassMembersDao classMembersDao;
    @Autowired
    private IGroupChatDao groupChatDao;
    @Autowired
    private IGroupMembersDao groupMembersDao;
    @Autowired
    private IClassParameterDao classParameterDao;
    @Autowired
    private IJobNameDao jobNameDao;
    @Autowired
    private IJobParameterDao jobParameterDao;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private IQuestionDao questionDao;
    @Autowired
    private ISubjectDao subjectDao;
    @Autowired
    private TencentUtil tencentUtil;

    /**
     * 获取省市区
     *
     * @return
     */
    @Override
    public GlobalReponse<List<ProvinceDto>> getAddress() {
        List<ProvinceDto> dtos = (List<ProvinceDto>) redisTemplate.opsForValue().get(Consts.ADMIN_ADDRESS);
        if (dtos!=null){
            return GlobalReponse.success(dtos);
        }
        ArrayList<ProvinceDto> provinceDtos = new ArrayList<>();
        List<AddressDto> allProvince = schoolDao.getAllProvince();
        for (AddressDto province : allProvince) {
            ProvinceDto provinceDto = new ProvinceDto();
            provinceDto.setProvinceId(province.getId());
            provinceDto.setProvinceName(province.getName());
            provinceDto.setAdcode(province.getAdcode());
            List<AddressDto> allCity = schoolDao.getAllCity(province.getId());
            ArrayList<CityDto> cityDtos = new ArrayList<>();
            for (AddressDto city : allCity) {
                CityDto cityDto = new CityDto();
                cityDto.setCityId(city.getId());
                cityDto.setCityName(city.getName());
                cityDto.setAdcode(city.getAdcode());
                List<AddressDto> allCounty = schoolDao.getAllCounty(city.getId());
                cityDto.setCountyList(allCounty);
                cityDtos.add(cityDto);
            }
            provinceDto.setCityList(cityDtos);
            provinceDtos.add(provinceDto);
        }
        //进行缓存
        redisTemplate.opsForValue().set(Consts.ADMIN_ADDRESS, provinceDtos);
        return GlobalReponse.success(provinceDtos);
    }

    /**
     * 新建学校
     *
     * @param schoolDto
     * @param userId
     * @return
     */
    @Override
    public GlobalReponse createSchool(SchoolDto schoolDto, Long userId) {
        String province = schoolDao.getProvince(schoolDto.getProvinceId());
        String city = schoolDao.getCity(schoolDto.getCityId());
        String county = schoolDao.getCounty(schoolDto.getCountyId());
        School school = new School();
        school.setProvince(province);
        school.setCity(city);
        school.setCounty(county);
        school.setName(schoolDto.getSchoolName());
        school.setIsDeleted(false);
        school.setCreateBy(userId.toString());
        school.setCreateTime(new Date());
        school.setType(1);
        schoolDao.insertTemplate(school);
        return GlobalReponse.success("创建成功");
    }

    /**
     * 查询学校分页
     *
     * @param pageNo
     * @param pageSize
     * @param schoolDto
     * @return
     */
    @Override
    public GlobalReponse<PageQuery<SchoolListDto>> schoolPage(Integer pageNo, Integer pageSize, SchoolDto schoolDto) {
        String province = schoolDao.getProvince(schoolDto.getProvinceId());
        String city = schoolDao.getCity(schoolDto.getCityId());
        String county = schoolDao.getCounty(schoolDto.getCountyId());
        PageQuery<SchoolListDto> query = new PageQuery<>();
        query.setPageNumber(pageNo);
        query.setPageSize(pageSize);
        query.setPara("province",province);
        query.setPara("city",city);
        query.setPara("county",county);
        query.setPara("schoolName",schoolDto.getSchoolName());
        query.setPara("userNickname",schoolDto.getUserNickname());
        schoolDao.schoolPage(query);
        List<SchoolListDto> list = query.getList();
        for (SchoolListDto dto : list) {
            if (dto.getType()==1){
                dto.setUserNickname(null);
                dto.setIsLocked(null);
            }else {
                if (dto.getUserId()!=null){
                    User user = userDao.unique(dto.getUserId());
                    dto.set("user",user);
                }
            }
        }
       query.setList(list);
        return GlobalReponse.success(query);
    }

    /**
     * 批量或者单个删除学校
     *
     * @param schoolIds
     * @return
     */
    @Override
    public GlobalReponse deletedSchool(String schoolIds,Long userId) {
        String schoolName=null;
        for (String s : schoolIds.split(",")) {
            Long id = Long.valueOf(s).longValue();
            School school = schoolDao.unique(id);
            List<ClassAnd> classAndList = classAndDao.createLambdaQuery().andEq(ClassAnd::getSchoolId, id).andEq(ClassAnd::getIsDeleted, false).select();
            if (classAndList.size()>0){
                if (school==null){
                    schoolName=school.getName();
                }else {
                    schoolName=schoolName+","+school.getName();
                }
            }else {
                school.setIsDeleted(true);
                school.setUpdateBy(userId.toString());
                school.setUpdateTime(new Date());
                schoolDao.updateTemplateById(school);
            }

        }
        if (schoolName!=null){
            return GlobalReponse.success(schoolName+"学校下有班级，请删除班级后再删除学校");
        }
        return GlobalReponse.success("删除成功");
    }

    /**
     * 学校展开，即查询学校的年级
     *
     * @param schoolId
     * @return
     */
    @Override
    public GlobalReponse getGradeBySchoolId(Long schoolId) {
        List<ClassAnd> classAnds = classAndDao.createLambdaQuery().andEq(ClassAnd::getSchoolId, schoolId).andEq(ClassAnd::getIsDeleted, false).select();
        Map<String, List<ClassAnd>> classMap = classAnds.stream().collect(Collectors.groupingBy(x -> x.getGradeDivision()));
        List<ClassAnd> primary = classMap.get("小学");
        List<ClassAnd> junior = classMap.get("初中");
        Map<String, Map> zMap = new HashMap<>();
        if (primary!=null){
            Map<String, List<ClassAnd>> classMapP = primary.stream().collect(Collectors.groupingBy(x -> x.getSchoolYear()));
            Set<Map.Entry<String, List<ClassAnd>>> entrySet = classMapP.entrySet();
            Map<String, SchoolToGradeDto> pMap = new HashMap<>();
            for (Map.Entry<String, List<ClassAnd>> entry : entrySet) {
                String key = entry.getKey();
                List<ClassAnd> value = entry.getValue();
                SchoolToGradeDto gradeClassDto = new SchoolToGradeDto();
                gradeClassDto.setSchoolYear(key);
                gradeClassDto.setClassNumber(value.size());
                for (ClassAnd classAnd : value) {
                    gradeClassDto.setStatus(classAnd.getStatus());

                }
                pMap.put(key,gradeClassDto);
            }
            zMap.put("小学",pMap);

        }
        if (junior!=null){
            Map<String, List<ClassAnd>> classMapJ = junior.stream().collect(Collectors.groupingBy(x -> x.getSchoolYear()));
            Set<Map.Entry<String, List<ClassAnd>>> entrySet1 = classMapJ.entrySet();
            Map<String, SchoolToGradeDto> jMap = new HashMap<>();
            for (Map.Entry<String, List<ClassAnd>> entry : entrySet1) {
                String key = entry.getKey();
                List<ClassAnd> value = entry.getValue();
                SchoolToGradeDto gradeClassDto = new SchoolToGradeDto();
                gradeClassDto.setSchoolYear(key);
                gradeClassDto.setClassNumber(value.size());
                for (ClassAnd classAnd : value) {
                    gradeClassDto.setStatus(classAnd.getStatus());

                }
                jMap.put(key,gradeClassDto);
            }
            zMap.put("初中",jMap);
        }
        if (zMap.size()==0){
            return GlobalReponse.success("暂无数据");
        }
        return GlobalReponse.success().setData(zMap);
    }

    /**
     * 年级展开，即查询年级下的班级
     *
     * @param schoolYear
     * @return
     */
    @Override
    public GlobalReponse<GradeToClassDto> getClassBySchoolYear(Long schoolId,String schoolYear) {
        List<ClassAnd> classAnds = classAndDao.createLambdaQuery().andEq(ClassAnd::getSchoolId, schoolId).andEq(ClassAnd::getSchoolYear, schoolYear).andEq(ClassAnd::getIsDeleted, false).select();
        List<GradeToClassDto> dtos = new ArrayList<>();
        for (ClassAnd classAnd : classAnds) {
            GradeToClassDto dto = new GradeToClassDto();
            //查询教师人数
            Long teacherNum = classAndService.countTeacher(classAnd.getId());
            //查询学生数量
            Long studentNum = classAndService.countStudent(classAnd.getId());
            User user = userDao.unique(classAnd.getCreateBy());
            dto.setId(classAnd.getId());
            dto.setName(classAnd.getName());
            dto.setClassNum(classAnd.getClassNum());
            dto.setStudentNum(studentNum);
            dto.setTeacherNum(teacherNum);
            dto.setUserNickname(user.getName());
            dtos.add(dto);
        }
        if (dtos.isEmpty()){
            return GlobalReponse.success("暂无数据");
        }
        return GlobalReponse.success(dtos);
    }

    /**
     * 后台删除班级
     *
     * @param classId
     * @return
     */
    @Override
    public GlobalReponse deletedClass(Long classId,Long userId) {
        List<ClassMembers> classMembers = classMembersDao.createLambdaQuery().andEq(ClassMembers::getClassId, classId).andEq(ClassMembers::getType, 1).andEq(ClassMembers::getIsDeleted, false).select();
        if (!classMembers.isEmpty()) {
            return GlobalReponse.fail("请移除全部学生后再删除班级");
        }
        ClassAnd classAnd = classAndDao.unique(classId);
        GroupChat groupChat = groupChatDao.createLambdaQuery().andEq(GroupChat::getClassId, classId).andEq(GroupChat::getIsDeleted, false).single();
        Boolean flag = tencentUtil.destroyGroup(groupChat.getId());
        if (flag) {
            classAnd.setIsDeleted(true);
            classAnd.setUpdateBy(userId.toString());
            classAnd.setUpdateTime(new Date());
            classAndDao.updateById(classAnd);
            groupChat.setIsDeleted(true);
            groupChat.setUpdateTime(new Date());
            groupChat.setUpdateBy(userId.toString());
            groupChatDao.updateTemplateById(groupChat);
            List<GroupMembers> groupMembers = groupMembersDao.createLambdaQuery().andEq(GroupMembers::getGroupChatId, groupChat.getId()).andEq(GroupMembers::getIsDeleted, false).select();
            for (GroupMembers groupMember : groupMembers) {
                groupMember.setIsDeleted(true);
                groupMember.setUpdateBy(userId.toString());
                groupMember.setUpdateTime(new Date());
                groupMembersDao.updateTemplateById(groupMember);
            }
            return GlobalReponse.success("删除成功");
        }
        return GlobalReponse.fail("删除失败");
    }

    /**
     * 查看班级详情
     *
     * @param classId
     * @return
     */
    @Override
    public GlobalReponse<ClassAndVo> getClassDetails(Long classId) {
        ClassAnd classAnd = classAndDao.unique(classId);
        ClassAndVo classAndVo = new ClassAndVo();
        classAndVo.setClassId(classAnd.getId());
        classAndVo.setClassNum(classAnd.getClassNum());
        classAndVo.setClassName(classAnd.getName());
        classAndVo.setClassStatus(classAnd.getStatus());
        classAndVo.setSchoolYear(classAnd.getSchoolYear());
        //查询学校信息
        School school = schoolDao.createLambdaQuery().andEq(School::getId,classAnd.getSchoolId()).andEq(School::getIsDeleted,false).single();
        classAndVo.setSchoolId(school.getId());
        classAndVo.setSchoolName(school.getName());
        classAndVo.setProvince(school.getProvince());
        classAndVo.setCity(school.getCity());
        classAndVo.setCounty(school.getCounty());
        //查询教师人数和列表
        Long teacherNum = classAndService.countTeacher(classAnd.getId());
        List<ClassMembers> teacher = classAndService.teacherList(classAnd.getId());
        ArrayList<TeacherAndStudentDto> teacherDtos = new ArrayList<>();
        for (ClassMembers members : teacher) {
            TeacherAndStudentDto dto = new TeacherAndStudentDto();
            if (members.getNickname()!=null){
                dto.setClassUserName(members.getNickname());
            }
            User user = userDao.unique(members.getUserId());
            dto.set("user",user);
            dto.setId(user.getId());
            dto.setNickname(user.getName());
            dto.setIsLocked(user.getIsLocked());
            dto.setHeadImage(user.getHeadImage());
            dto.setSex(user.getSex());
            dto.setMobile(user.getMobile());
            List<Question> questions = questionDao.createLambdaQuery().andEq(Question::getWarehouseType, 1).andEq(Question::getCreateBy, user.getId()).andEq(Question::getIsDeleted, false).select();
            List<Long> collect = questions.stream().map(Question::getSubjectId).collect(Collectors.toList());
            String subject=null;
            if (!collect.isEmpty()) {
                List<Subject> list = subjectDao.createLambdaQuery().andEq(Subject::getIsDeleted, false).andIn(Subject::getId, collect).select();
                for (Subject subject1 : list) {
                    if (subject1.getName()!=null){
                        if (subject==null){
                            subject=subject1.getName();
                        }else {
                            subject=subject+","+subject1.getName();
                        }
                    }
                }
            }
            dto.setSubjects(subject);
            teacherDtos.add(dto);
        }
        classAndVo.setTeacherDtoList(teacherDtos);
        classAndVo.setTeacherNum(teacherNum);
        //查询学生数量和列表
        Long studentNum = classAndService.countStudent(classAnd.getId());
        List<ClassMembers> student = classAndService.studentList(classAnd.getId());
        ArrayList<TeacherAndStudentDto> studentDtos = new ArrayList<>();
        for (ClassMembers members : student) {
            TeacherAndStudentDto dto = new TeacherAndStudentDto();
            if (members.getNickname()!=null){
                dto.setClassUserName(members.getNickname());
            }
            User user = userDao.unique(members.getUserId());
            dto.set("user",user);
            dto.setId(user.getId());
            dto.setNickname(user.getName());
            dto.setIsLocked(user.getIsLocked());
            dto.setHeadImage(user.getHeadImage());
            dto.setSex(user.getSex());
            dto.setMobile(user.getMobile());
            studentDtos.add(dto);
        }
        classAndVo.setStudentNum(studentNum);
        classAndVo.setStudentDtoList(studentDtos);
        //查询创建人
        User user = userDao.unique(classAnd.getCreateBy());
        classAndVo.setCreateId(user.getId());
        classAndVo.setCreateName(user.getName());
        classAndVo.setCreateImage(user.getHeadImage());
        return GlobalReponse.success(classAndVo);
    }

    /**
     * 获取班级参数
     *
     * @return
     */
    @Override
    public GlobalReponse<ClassParameterDto> getClassParameter() {
        ClassParameter classParameter = classParameterDao.createLambdaQuery().andEq(ClassParameter::getIsDeleted, false).single();
        ClassParameterDto dto = new ClassParameterDto();
        dto.setId(classParameter.getId());
        dto.setAutumnTime(classParameter.getAutumnTime());
        dto.setSpringTime(classParameter.getSpringTime());
        dto.setEducationSystem(classParameter.getEducationSystem());
        return GlobalReponse.success(dto);
    }

    /**
     * 班级参数设置
     *
     * @param dto
     * @param userId
     * @return
     */
    @Override
    public GlobalReponse setClassParameter(ClassParameterDto dto, Long userId) {
        if (dto.getId() == null){
            ClassParameter classParameter = new ClassParameter();
            classParameter.setAutumnTime(dto.getAutumnTime());
            classParameter.setSpringTime(dto.getSpringTime());
            classParameter.setEducationSystem(dto.getEducationSystem());
            classParameter.setCreateBy(userId.toString());
            classParameter.setCreateTime(new Date());
            classParameter.setIsDeleted(false);
            classParameterDao.insertTemplate(classParameter);
        }
        if (dto.getId() != null){
            ClassParameter parameter = classParameterDao.unique(dto.getId());
            parameter.setAutumnTime(dto.getAutumnTime());
            parameter.setSpringTime(dto.getSpringTime());
            parameter.setEducationSystem(dto.getEducationSystem());
            parameter.setUpdateBy(userId.toString());
            parameter.setUpdateTime(new Date());
            classParameterDao.updateTemplateById(parameter);
        }
        return GlobalReponse.success("编辑成功");
    }

    /**
     * 获取作业名称
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public GlobalReponse<PageQuery<JobNameDto>> getJobName(Integer pageNo, Integer pageSize) {
        PageQuery<JobName> query = new PageQuery<>();
        query.setPageNumber(pageNo);
        query.setPageSize(pageSize);
        jobNameDao.pageQuery(query);
        List<JobNameDto> dtos = new ArrayList<>();
        for (JobName jobName : query.getList()) {
            JobNameDto dto = new JobNameDto();
            dto.setId(jobName.getId());
            dto.setName(jobName.getName());
            dtos.add(dto);
        }
        query.setList(dtos);
        return GlobalReponse.success(query);
    }

    /**
     * 新增或编辑作业名称
     *
     * @param dto
     * @param userId
     * @return
     */
    @Override
    public GlobalReponse createJobName(JobNameDto dto, Long userId) {
        //编辑
        if (dto.getId()!=null){
            JobName jobName = jobNameDao.unique(dto.getId());
            jobName.setName(dto.getName());
            jobName.setUpdateBy(userId.toString());
            jobName.setUpdateTime(new Date());
            jobNameDao.updateTemplateById(jobName);
            return GlobalReponse.success("编辑成功");
        }

        //新增
        if (dto.getId()==null){
            JobName single = jobNameDao.createLambdaQuery().andEq(JobName::getName, dto.getName()).andEq(JobName::getIsDeleted, false).single();
            if (single!=null){
                return GlobalReponse.fail("该名称已存在，请重新添加");
            }
            JobName jobName = new JobName();
            jobName.setName(dto.getName());
            jobName.setCreateBy(userId.toString());
            jobName.setCreateTime(new Date());
            jobName.setIsDeleted(false);
            jobNameDao.insertTemplate(jobName);
            return GlobalReponse.success("添加成功");
        }
        return GlobalReponse.fail("操作失败");
    }

    /**
     * 删除作业名称
     *
     * @param jobNameId
     * @param userId
     * @return
     */
    @Override
    public GlobalReponse deletedJobName(String jobNameId, Long userId) {
        for (String s : jobNameId.split(",")) {
            Long id = Long.valueOf(s).longValue();
            JobName jobName = jobNameDao.unique(id);
            if (jobName!=null){
                jobName.setUpdateBy(userId.toString());
                jobName.setUpdateTime(new Date());
                jobName.setIsDeleted(true);
                jobNameDao.updateTemplateById(jobName);
            }
        }
        return GlobalReponse.success("删除成功");
    }

    /**
     * 获取作业参数
     *
     * @return
     */
    @Override
    public GlobalReponse<JobParameterDto> getJobParameter() {
        JobParameter single = jobParameterDao.createLambdaQuery().andEq(JobParameter::getIsDeleted, false).single();
        JobParameterDto dto = new JobParameterDto();
        dto.setId(single.getId());
        dto.setAccuracy(single.getAccuracy());
        dto.setMinute(single.getMinute());
        dto.setScore(single.getScore());
        return GlobalReponse.success(dto);
    }

    /**
     * 获取作业参数
     * @param dto
     * @param userId
     * @return
     */
    @Override
    public GlobalReponse setJobParameter(JobParameterDto dto, Long userId) {
        if (dto.getId() == null){
            return GlobalReponse.fail("请传入正确的参数");
        }
        if (dto.getId() != null){
            JobParameter jobParameter = jobParameterDao.unique(dto.getId());
            jobParameter.setAccuracy(dto.getAccuracy());
            jobParameter.setMinute(dto.getMinute());
            jobParameter.setScore(dto.getScore());
            jobParameter.setUpdateBy(userId.toString());
            jobParameter.setUpdateTime(new Date());
            jobParameterDao.updateTemplateById(jobParameter);
        }
        return GlobalReponse.success("编辑成功");
    }
}
